﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using MShop.Core.Domain;
using MShop.Web.Models;
using MShop.Core.DataAccess;
using MShop.Core.Extensions;
using MShop.Core;
using MShop.Core.Service.Membership;
using MShop.Core.Service.EmailSender;

namespace MShop.Web.Controllers
{


    public class AccountController : ControllerBase
    {
        private readonly ICommonDao<aspnet_Users> _CommonDao;
        private readonly ICommonDao<aspnet_Roles> _CommonDao2;
        private readonly ICommonDao<ShopUsersCryptography> _CommonDao3;
        private readonly IMenuDao _MenuDao;
        private readonly ICommonDao<ShopUsers> _CommonShopUsers;
        private readonly ICommonDao<ShopUserRights> _CommonShopUserRights;
        private readonly IRoleService _RoleService;
        private readonly IShopContext _ShopContext;
        private readonly ICartItemDao _CartItemDao;
        private readonly IEmailSender _EmailSender;
        public AccountController(ICommonDao<aspnet_Users> commonDao, ICommonDao<aspnet_Roles> commonDao2,
            ICommonDao<ShopUsers> commonShopUsers,IMenuDao _menuDao,ICommonDao<ShopUserRights> commonShopUserRights,
            IRoleService roleService,IShopContext shopContext,ICartItemDao cartItemDao, ICommonDao<ShopUsersCryptography> commonDao3,IEmailSender emailSender)
        {
            _CommonDao = commonDao;
            _CommonDao2 = commonDao2;
            _CommonDao3 = commonDao3;
            _MenuDao = _menuDao;
            _CommonShopUsers = commonShopUsers;
            _CommonShopUserRights = commonShopUserRights;
            _RoleService = roleService;
            _ShopContext = shopContext;
            _CartItemDao = cartItemDao;
            _EmailSender = emailSender;
        }


        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }
            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            AppendMeta("用户登录");
            return View();
        }

        [HttpPost]
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            AppendMeta("用户登录");
            if (ModelState.IsValid)
            {
               if (MembershipService.ValidateUser(model.UserName, model.Password))
               {
                   #region "power"
                   if (_RoleService.IsPowerRole(model.UserName))
                   {
                       Session["IsAuthorized"] = true;
                       aspnet_Users user = _CommonDao.Find(x => x.UserName == model.UserName).First();
                       user.ShopUserRights.Where(x => x.UserId == user.UserId).ToList().ForEach((x) =>
                       {
                           _CommonDao.Delete(x);
                       });

                       string[] roles = Roles.GetRolesForUser(model.UserName);
                       aspnet_Roles[] myroles = _CommonDao2.Find(x => roles.Contains(x.RoleName)).ToArray();

                       List<ShopUserRights> userrights = new List<ShopUserRights>();

                       foreach (var item in myroles)
                       {
                           foreach (Menu menu in _MenuDao.GetAll())
                           {
                               Powers[] powers = menu.Powers.Where(x => x.RoleId == item.RoleId).ToArray();
                               foreach (var p in powers)
                               {

                                   RightFlags flag = (RightFlags)p.Rights;
                                   ShopUserRights right = new ShopUserRights()
                                   {
                                       UserId = user.UserId,
                                       Rights = p.Rights,
                                       MenuId = p.MenuId

                                   };
                                   if (!userrights.Contains(right))
                                   {
                                       userrights.Add(right);
                                   }
                                   else
                                   {
                                       ShopUserRights rightinstance = userrights.Find(x => (x.MenuId == right.MenuId && x.UserId == right.UserId));
                                       if ((flag & RightFlags.NoRight) != 0)
                                       {
                                           flag = flag & (~RightFlags.NoRight);
                                       }
                                       rightinstance.RightFlags = rightinstance.RightFlags | flag;

                                       if ((rightinstance.RightFlags & RightFlags.Create) != 0
                                           || (rightinstance.RightFlags & RightFlags.Delete) != 0
                                           || (rightinstance.RightFlags & RightFlags.Edit) != 0
                                           || (rightinstance.RightFlags & RightFlags.Inspection) != 0
                                           || (rightinstance.RightFlags & RightFlags.Print) != 0
                                           || (rightinstance.RightFlags & RightFlags.View) != 0)
                                       {
                                           if ((rightinstance.RightFlags & RightFlags.NoRight) != 0)
                                           {
                                               rightinstance.RightFlags = rightinstance.RightFlags & (~RightFlags.NoRight);
                                           }
                                       }
                                   }

                               }
                           }
                       }

                       foreach (var item in userrights)
                       {
                           _CommonShopUserRights.Save(item);
                       }

                       _CommonShopUserRights.SaveChanges();
                   }
                   #endregion

                   //验证
                    FormsService.SignIn(model.UserName, model.RememberMe);
                    
                 
                    MembershipUser muser= Membership.GetUser(model.UserName);

                    Guid userid=new Guid(muser.ProviderUserKey.ToString());

                    ShopUsersCryptography crypt = _CommonDao3.FirstOrDefault(x => x.UserId == userid);
                    ShopUsers suser = _CommonShopUsers.FirstOrDefault(x => x.UserId == userid);
                    if (suser == null)
                    {
                        suser = new ShopUsers() { UserId = userid };
                        suser.LastLoginDate = DateTime.Now;
                        _CommonShopUsers.Save(suser);
                        _CommonShopUsers.SaveChanges();
                    }
                    else
                    {
                        suser.LastLoginDate = DateTime.Now;
                        _CommonShopUsers.SaveChanges();
                    }
                    
                    if (crypt == null)
                    {
                        crypt = new ShopUsersCryptography() { UserId = userid, Point = 0, Balance = 0 };
                        _CommonDao3.Save(crypt);
                        _CartItemDao.SaveChanges();
                    }
                    HttpCookie cookie = Request.Cookies["SessionId"];

                    if (cookie != null)
                    {                       
                        _CartItemDao.UpdateCartItem(cookie.Value, userid);
                        _CartItemDao.SaveChanges();
                    }
                    
                  

                    if (!String.IsNullOrEmpty(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "用户名或密码错误！");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            FormsService.SignOut();

            return RedirectToAction("Index", "Home");
        }
 
      
        public ActionResult Register()
        {
            AppendMeta("用户注册");
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            var model = new RegisterModel();
            return View(model);
        }

     
        [HttpPost]
        public ActionResult Register(RegisterModel model)
        {
            AppendMeta("用户注册");
           if (ModelState.IsValid)
            {
                // Attempt to register the user
                MembershipCreateStatus createStatus = MembershipService.CreateUser(model.UserName, model.Password, model.Email);


                if (createStatus == MembershipCreateStatus.Success)
                {
                    aspnet_Users user = _CommonDao.Find(x => x.UserName == model.UserName).First();
                    ShopUsers faouser = new ShopUsers();
                    faouser.DeptId = model.DepartMentId;
                    faouser.UserId = user.UserId;
                    faouser.RoleId = _ShopContext.Settings.RoleId;

                    ShopUsersCryptography crypt = new ShopUsersCryptography();
                    crypt.UserId = user.UserId;
                    crypt.Balance = 0;
                    crypt.Point = 0;
                    _CommonShopUsers.Save(faouser);
                    _CommonDao3.Save(crypt);

                    _CommonShopUsers.Save(faouser);
                    _CommonShopUsers.SaveChanges();
                 
                    aspnet_Roles role = this._RoleService.FindRoles().FirstOrDefault(x => x.RoleId == _ShopContext.Settings.RoleId);
                  

                    if (role != null)
                    {
                        Roles.AddUserToRole(model.UserName, role.RoleName);
                    }
                    //发送邮件
                    SendSync(model);
                    return RedirectToAction("Success","Account");
                }
                else
                {
                    ModelState.AddModelError("", AccountValidation.ErrorCodeToString(createStatus));
                }
            }           
            ViewData["roles"] = _CommonDao2.GetAll().ConvertListItem("rolename", "rolename");
            // If we got this far, something failed, redisplay form
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View(model);
        }

        protected void SendSync(RegisterModel regiser)
        {
             //发送邮件
            AccountCreatedEmail email = new AccountCreatedEmail()
            {
                Email = regiser.Email,
                Password = regiser.Password,
                UserName = regiser.UserName,                
            };

            _EmailSender.SendAsync(email, null);
           
        }

        public ActionResult Success()
        {
            AppendMeta("用户注册成功");          

            return View();
        }
 

    }
}
